home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 26 / AACD 26.iso / AACD / Programming / ace_gpl_release / src_ansi / ace / c / sym.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-01-05  |  17.7 KB  |  852 lines

  1. /* << ACE >>
  2.  
  3.    -- Amiga BASIC compiler --
  4.  
  5.    ** Symbol Table Management & Code Generation **
  6.    ** Copyright (C) 1998 David Benn
  7.    ** 
  8.    ** This program is free software; you can redistribute it and/or
  9.    ** modify it under the terms of the GNU General Public License
  10.    ** as published by the Free Software Foundation; either version 2
  11.    ** of the License, or (at your option) any later version.
  12.    **
  13.    ** This program is distributed in the hope that it will be useful,
  14.    ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.    ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.    ** GNU General Public License for more details.
  17.    **
  18.    ** You should have received a copy of the GNU General Public License
  19.    ** along with this program; if not, write to the Free Software
  20.    ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  21.  
  22.    Author: David J Benn
  23.    Date: 26th October-25th November, 2nd-13th December 1991,
  24.    27th January 1992, 8th-9th, 25th February 1992,
  25.    21st April 1992,
  26.    8th,9th,13th,14th,28th June 1992,
  27.    2nd,3rd,4th,5th,17th,26th,28th,29th July 1992,
  28.    1st-3rd,8th,9th August 1992,
  29.    6th,22nd,29th December 1992,
  30.    13th January 1993,
  31.    2nd,28th February 1993,
  32.    12th,20th April 1993,
  33.    15th-18th,28th December 1993,
  34.    7th January 1994,
  35.    26th February 1994,
  36.    12th June 1994,
  37.    20th August 1994,
  38.    10th September 1994
  39.  */
  40.  
  41. #include <string.h>
  42. #include "symvar.h"
  43.  
  44. /* -- general functions -- */
  45. void kill_all_lists (void)
  46. {
  47.   lev = ONE;
  48.   while (lev >= ZERO)
  49.     {
  50.       kill_symtab ();
  51.       --lev;
  52.     }
  53.   puts ("freeing code list...");
  54.   kill_code ();            /* all other lists are freed by cleanup() */
  55. }
  56.  
  57. /* -- symbol table functions -- */
  58. void new_symtab (void)
  59. {
  60. /* create a new symbol table
  61.    at current level.
  62.  */
  63.  
  64.   if ((tab_head[lev] = (SYM *) sym_alloc (sizeof (SYM), MEMF_ANY)) == NULL)
  65.     {
  66.       printf ("Can't allocate memory for symbol table!\n");
  67.       early_exit = TRUE;
  68.       kill_all_lists ();
  69.       cleanup ();
  70.     }
  71.   tab_head[lev]->next = NULL;
  72. }
  73.  
  74. void kill_symtab (void)
  75. {
  76. /* free memory held by 
  77.    symbol table. 
  78.  */
  79.  
  80.   free_sym_alloc ();
  81. }
  82.  
  83. void find_tab_tail (void)
  84. {
  85. /* find the end of the 
  86.    symbol table at current
  87.    level.
  88.  */
  89.  
  90.   tab_tail = tab_head[lev];
  91.   while (tab_tail->next != NULL)
  92.     tab_tail = tab_tail->next;
  93. }
  94.  
  95. BOOL exist (char *name, int obj)
  96. {
  97.   int oldlevel;
  98.  
  99.   oldlevel = lev;
  100.  
  101.   if ((obj == subprogram) || (obj == function) ||
  102.       (obj == definedfunc) || (obj == extfunc) || (obj == extvar) ||
  103.       (obj == constant) || (obj == structdef))
  104.     lev = ZERO;
  105.  
  106.   curr_item = tab_head[lev]->next;
  107.   while (curr_item != NULL)
  108.     {
  109.       if ((strcmp (curr_item->name, name) == 0) && (curr_item->object == obj))
  110.     {
  111.       lev = oldlevel;
  112.       return (TRUE);
  113.     }
  114.       else
  115.     curr_item = curr_item->next;
  116.     }
  117.  
  118.   lev = oldlevel;
  119.   return (FALSE);
  120. }
  121.  
  122. void enter (char *name, int typ, int obj, int dims)
  123. /* enter a symbol into symbol table */
  124. {
  125.   int i;
  126.  
  127.   /* allocate memory for info' */
  128.   if ((new_item = (SYM *) sym_alloc (sizeof (SYM), MEMF_ANY)) == NULL)
  129.     {
  130.       printf ("Can't allocate memory for symbol table item!\n");
  131.       early_exit = TRUE;
  132.       kill_all_lists ();
  133.       cleanup ();
  134.     }
  135.  
  136.   if ((new_item->name = (char *) sym_alloc (strlen (name) + 1, MEMF_ANY)) == NULL)
  137.     {
  138.       printf ("Can't allocate memory for symbol table item!\n");
  139.       early_exit = TRUE;
  140.       kill_all_lists ();
  141.       cleanup ();
  142.     }
  143.  
  144.   /* fill the node with info' */
  145.   strcpy (new_item->name, name);
  146.   new_item->type = typ;
  147.   new_item->object = obj;
  148.   new_item->dims = dims;
  149.  
  150.   /* string defaults */
  151.   if ((typ == stringtype) && (obj != array))
  152.     {
  153.       new_item->new_string_var = TRUE;
  154.       new_item->decl = undeclared;
  155.       new_item->size = MAXSTRLEN;
  156.     }
  157.  
  158.   if ((obj != label) && (obj != function) && (obj != constant) &&
  159.       (obj != extvar) && (obj != extfunc) && (obj != structdef))
  160.     {
  161.       /* how many bytes to reserve? */
  162.       if ((typ == shorttype) && (obj != array))
  163.     addr[lev] += 2;
  164.       else
  165.     addr[lev] += 4;        /* long, single, string, array, sub, structure */
  166.  
  167.       new_item->address = addr[lev];
  168.     }
  169.   else
  170.     new_item->address = 0;
  171.  
  172.   new_item->level = lev;
  173.   new_item->shared = FALSE;    /* shared may be explicitly SET later */
  174.  
  175.   /* array? -> store index maxima */
  176.   if (obj == array)
  177.     {
  178.       if ((new_item->index = (SHORT *) sym_alloc ((dims + 1) * 2, MEMF_ANY)) == NULL)
  179.     {
  180.       printf ("Array index storage allocation error.\n");
  181.       early_exit = TRUE;
  182.       kill_all_lists ();
  183.       cleanup ();
  184.     }
  185.       else
  186.     for (i = 0; i <= dims; i++)
  187.       new_item->index[i] = dimsize[i];
  188.     }
  189.  
  190.   /* setup for structure definition */
  191.   if (obj == structdef)
  192.     {
  193.       if ((new_item->structmem =
  194.        (STRUCM *) sym_alloc (sizeof (STRUCM), MEMF_ANY)) == NULL)
  195.     {
  196.       printf ("Can't allocate memory for an initial structdef node!\n");
  197.       early_exit = TRUE;
  198.       kill_all_lists ();
  199.       cleanup ();
  200.     }
  201.       else
  202.     {
  203.       new_item->structmem->next = NULL;
  204.       new_item->size = 0;
  205.     }
  206.     }
  207.  
  208.   /* link item into symbol table */
  209.  
  210.   find_tab_tail ();
  211. /* find_tab_tail(tab_head[lev]); */
  212.  
  213.   tab_tail->next = new_item;
  214.   new_item->next = NULL;
  215.   curr_item = new_item;
  216. }
  217.  
  218. /*
  219.    void show_table_item(SYM *item)
  220.    {
  221.    printf("%10s\t",item->name);
  222.    showtyp(item->type);
  223.    showobj(item->object);
  224.    printf("%5d\t%5d\t%5d\n",item->dims,item->address,item->level);
  225.    }
  226.  */
  227.  
  228. /* --code generator functions-- */
  229.  
  230. void create_lists (void)
  231. {
  232. /* create code, DATA, BSS, XREF and BASIC DATA lists */
  233.  
  234.   data = (DATA *) alloc (sizeof (DATA), MEMF_ANY);
  235.   if (data == NULL)
  236.     {
  237.       cleanup ();
  238.     }
  239.   else
  240.     {
  241.       curr_data = data;
  242.       data->next = NULL;
  243.     }
  244.  
  245.   bss = (BSS *) alloc (sizeof (BSS), MEMF_ANY);
  246.   if (bss == NULL)
  247.     {
  248.       cleanup ();
  249.     }
  250.   else
  251.     {
  252.       curr_bss = bss;
  253.       bss->next = NULL;
  254.     }
  255.  
  256.   xref = (XREF *) alloc (sizeof (XREF), MEMF_ANY);
  257.   if (xref == NULL)
  258.     {
  259.       cleanup ();
  260.     }
  261.   else
  262.     {
  263.       curr_xref = xref;
  264.       xref->next = NULL;
  265.     }
  266.  
  267.   basdata = (BASDATA *) alloc (sizeof (BASDATA), MEMF_ANY);
  268.   if (basdata == NULL)
  269.     {
  270.       cleanup ();
  271.     }
  272.   else
  273.     {
  274.       curr_basdata = basdata;
  275.       basdata->next = NULL;
  276.     }
  277.  
  278.   code = (CODE *) alloc_code ("  ", "  ", "  ");    /* first node is a dummy */
  279.   if (code == NULL)
  280.     {
  281.       cleanup ();
  282.     }
  283.   else
  284.     {
  285.       curr_code = code;
  286.       code->next = NULL;
  287.     }
  288. }
  289.  
  290. BOOL is_a_label (char *opc)
  291. {
  292.   int cc = 0;
  293.  
  294.   while (opc[cc] != '\0')
  295.     cc++;
  296.   if (opc[cc - 1] == ':')
  297.     return (TRUE);
  298.   else
  299.     return (FALSE);
  300. }
  301.  
  302. void write_code (CODE * line)
  303. {
  304.   if (strcmp (line->opcode, "nop") != 0)
  305.     {
  306.       if (!is_a_label (line->opcode))
  307.     {
  308.       fprintf (dest, "\t%s", line->opcode);
  309.       fprintf (dest, "\t%s", line->srcopr);
  310.       if (line->destopr[0] != ' ')
  311.         fprintf (dest, ",%s\n", line->destopr);    /* comma & destopr */
  312.       else
  313.         fprintf (dest, "\n");    /* no destopr, so just LF */
  314.     }
  315.       else
  316.     fprintf (dest, "%s\n", line->opcode);    /* label starts in 1st column */
  317.     }
  318. }
  319.  
  320. BOOL label_undef (CODE * node)
  321. {
  322.   char buf[50];
  323.  
  324.   if ((strcmp (node->opcode, "jmp") == 0) ||
  325.       (strcmp (node->opcode, "jsr") == 0))
  326.     {
  327.       if (strcmp (node->destopr, "* ") == 0)
  328.     {
  329.       /* undefined label at time of jmp/jsr */
  330.       strcpy (buf, node->srcopr);
  331.       strcat (buf, ":\0");
  332.       /* has it been defined since jmp/jsr? */
  333.       if (exist (buf, label))
  334.         {
  335.           strcpy (node->destopr, "  ");
  336.           return (FALSE);
  337.         }            /* not UNdefined */
  338.       else
  339.         {
  340.           early_exit = TRUE;
  341.           return (TRUE);    /* undefined */
  342.         }
  343.     }
  344.       else
  345.     return (FALSE);        /* not UNdefined */
  346.     }
  347.   else
  348.     return (FALSE);        /* not a branch instruction */
  349. }
  350.  
  351. void undef_label_check (void)
  352. {
  353.   BOOL past_head = FALSE;
  354.  
  355.   /* check for undefined labels */
  356.   curr_code = code;
  357.   while (curr_code->next != NULL)
  358.     {
  359.       if (past_head)
  360.     {
  361.       if (label_undef (curr_code))
  362.         {
  363.           _error (8);
  364.           printf ("'%s'\n", curr_code->srcopr);
  365.         }
  366.     }
  367.       curr_code = curr_code->next;
  368.       if (!past_head)
  369.     past_head = TRUE;
  370.     }
  371.   if (label_undef (curr_code))
  372.     {
  373.       _error (8);
  374.       printf ("'%s'\n", curr_code->srcopr);
  375.     }
  376. }
  377.  
  378. void kill_code (void)
  379. {
  380.   BOOL past_head = FALSE;
  381.   CODE *curr, *temp;
  382.  
  383.   curr = code;
  384.  
  385.   do
  386.     {
  387.       temp = curr;
  388.       curr = curr->next;
  389.       if (past_head)
  390.     {
  391.       if (!early_exit)
  392.         write_code (temp);
  393.  
  394.       /* free all the struct's memory */
  395.       free_code (temp);
  396.     }
  397.  
  398.       if (!past_head)
  399.     past_head = TRUE;
  400.     }
  401.   while (curr != NULL);
  402.  
  403.   /* free the dummy head node's memory */
  404.   free_code (code);
  405. }
  406.  
  407. void gen (char *opcode, char *srcopr, char *destopr)
  408. {
  409.   /* allocate memory for a new node & each field */
  410.   if ((new_code = (CODE *) alloc_code (opcode, srcopr, destopr)) == NULL)
  411.     {
  412.       printf ("Can't allocate memory for code node!\n");
  413.       early_exit = TRUE;
  414.       kill_all_lists ();
  415.       cleanup ();
  416.     }
  417.  
  418.   /* fill code struct */
  419.   strcpy (new_code->opcode, opcode);
  420.   strcpy (new_code->srcopr, srcopr);
  421.   strcpy (new_code->destopr, destopr);
  422.  
  423.   new_code->next = NULL;
  424.   curr_code->next = new_code;
  425.   curr_code = curr_code->next;
  426. }
  427.  
  428. void change (CODE * cx, char *opcode, char *srcopr, char *destopr)
  429. {
  430.   /* free the old fields */
  431.   free_code_members (cx);
  432.  
  433.   /* allocate memory & insert new instruction & operands */
  434.   if ((BOOL) alloc_code_members (cx, opcode, srcopr, destopr))
  435.     {
  436.       strcpy (cx->opcode, opcode);
  437.       strcpy (cx->srcopr, srcopr);
  438.       strcpy (cx->destopr, destopr);
  439.     }
  440.   else
  441.     {
  442.       printf ("Can't allocate memory for CODE node fields!\n");
  443.       early_exit = TRUE;
  444.       kill_all_lists ();
  445.       cleanup ();
  446.     }
  447. }
  448.  
  449. /* --DATA list functions-- */
  450.  
  451. BOOL exist_DATA (char *name)
  452. {
  453.   DATA *curr;
  454.   curr = data->next;
  455.   while (curr != NULL)
  456.     {
  457.       if (strcmp (curr->name, name) == 0)
  458.     return (TRUE);
  459.       else
  460.     curr = curr->next;
  461.     }
  462.   return (FALSE);
  463. }
  464.  
  465. void enter_DATA (char *name, char *literal)
  466. {
  467.   if (exist_DATA (name))
  468.     return;            /* already exists */
  469.  
  470.   /* allocate memory for a new node & each field */
  471.   if ((new_data = (DATA *) alloc (sizeof (DATA), MEMF_ANY)) == NULL)
  472.     {
  473.       printf ("Can't allocate memory for DATA node!\n");
  474.       early_exit = TRUE;
  475.       kill_all_lists ();
  476.       cleanup ();
  477.     }
  478.  
  479.   if ((new_data->name = (char *) alloc (strlen (name) + 1, MEMF_ANY)) == NULL)
  480.     {
  481.       printf ("Can't allocate memory for DATA node name field!\n");
  482.       early_exit = TRUE;
  483.       kill_all_lists ();
  484.       cleanup ();
  485.     }
  486.  
  487.   if ((new_data->literal = (char *) alloc (strlen (literal) + 1, MEMF_ANY)) == NULL)
  488.     {
  489.       printf ("Can't allocate memory for DATA node literal field!\n");
  490.       early_exit = TRUE;
  491.       kill_all_lists ();
  492.       cleanup ();
  493.     }
  494.  
  495.   /* fill DATA struct */
  496.   strcpy (new_data->name, name);
  497.   strcpy (new_data->literal, literal);
  498.  
  499.   new_data->next = NULL;
  500.   curr_data->next = new_data;
  501.   curr_data = curr_data->next;
  502. }
  503.  
  504. void write_data (void)
  505. {
  506.   BOOL past_head = FALSE;
  507.   DATA *curr, *temp;
  508.  
  509.   curr = data;
  510.   if (curr->next != NULL)
  511.     {
  512.       fprintf (dest, "\n\tSECTION data,DATA\n\n");
  513.     }
  514.  
  515.   do
  516.     {
  517.       temp = curr;
  518.       curr = curr->next;
  519.       if (past_head)
  520.     {
  521.       fprintf (dest, "%s\t%s\n", temp->name, temp->literal);
  522.     }
  523.       if (!past_head)
  524.     past_head = TRUE;
  525.     }
  526.   while (curr != NULL);
  527. }
  528.  
  529. /* --BSS list functions-- */
  530.  
  531. BOOL exist_BSS (char *name)
  532. {
  533.   BSS *curr;
  534.   curr = bss->next;
  535.   while (curr != NULL)
  536.     {
  537.       if (strcmp (curr->name, name) == 0)
  538.     return (TRUE);
  539.       else
  540.     curr = curr->next;
  541.     }
  542.   return (FALSE);
  543. }
  544.  
  545. void enter_BSS (char *name, char *store)
  546. {
  547.   /* ignore if already exists, except if name is "  " 
  548.      which is used for structure declarations */
  549.   if ((exist_BSS (name)) && (strcmp (name, "  ") != 0))
  550.     return;
  551.  
  552.   /* allocate memory for a new node & each field */
  553.   if ((new_bss = (BSS *) alloc (sizeof (BSS), MEMF_ANY)) == NULL)
  554.     {
  555.       printf ("Can't allocate memory for BSS node!\n");
  556.       early_exit = TRUE;
  557.       kill_all_lists ();
  558.       cleanup ();
  559.     }
  560.  
  561.   if ((new_bss->name = (char *) alloc (strlen (name) + 1, MEMF_ANY)) == NULL)
  562.     {
  563.       printf ("Can't allocate memory for BSS node name field!\n");
  564.       early_exit = TRUE;
  565.       kill_all_lists ();
  566.       cleanup ();
  567.     }
  568.  
  569.   if ((new_bss->store = (char *) alloc (strlen (store) + 1, MEMF_ANY)) == NULL)
  570.     {
  571.       printf ("Can't allocate memory for BSS node literal field!\n");
  572.       early_exit = TRUE;
  573.       kill_all_lists ();
  574.       cleanup ();
  575.     }
  576.  
  577.   /* fill BSS struct */
  578.   strcpy (new_bss->name, name);
  579.   strcpy (new_bss->store, store);
  580.  
  581.   new_bss->next = NULL;
  582.   curr_bss->next = new_bss;
  583.   curr_bss = curr_bss->next;
  584. }
  585.  
  586. void write_bss (void)
  587. {
  588.   BOOL past_head = FALSE;
  589.   BSS *curr, *temp;
  590.  
  591.   curr = bss;
  592.   if (curr->next != NULL)
  593.     {
  594.       fprintf (dest, "\n\tSECTION mem,BSS\n\n");
  595.     }
  596.  
  597.   do
  598.     {
  599.       temp = curr;
  600.       curr = curr->next;
  601.       if (past_head)
  602.     {
  603.       fprintf (dest, "%s\t%s\n", temp->name, temp->store);
  604.     }
  605.       if (!past_head)
  606.     past_head = TRUE;
  607.     }
  608.   while (curr != NULL);
  609. }
  610.  
  611. /* --XREF list functions-- */
  612.  
  613. BOOL exist_XREF (char *name)
  614. {
  615.   XREF *curr;
  616.  
  617.   curr = xref->next;
  618.   while (curr != NULL)
  619.     {
  620.       if (strcmp (curr->name, name) == 0)
  621.     return (TRUE);
  622.       else
  623.     curr = curr->next;
  624.     }
  625.   return (FALSE);
  626. }
  627.  
  628. void enter_XREF (char *name)
  629. {
  630.   if (exist_XREF (name))
  631.     return;            /* already exists */
  632.  
  633.   if (strcmp (name, "_DOSBase") == 0)
  634.     dosused = TRUE;
  635.   if (strcmp (name, "_MathBase") == 0)
  636.     mathffpused = TRUE;
  637.   if (strcmp (name, "_MathTransBase") == 0)
  638.     mathtransused = TRUE;
  639.   if (strcmp (name, "_GfxBase") == 0)
  640.     gfxused = TRUE;
  641.   if (strcmp (name, "_IntuitionBase") == 0)
  642.     intuitionused = TRUE;
  643.   if (strcmp (name, "_TransBase") == 0)
  644.     translateused = TRUE;
  645.  
  646.   /* allocate memory for a new node & name field */
  647.   if ((new_xref = (XREF *) alloc (sizeof (XREF), MEMF_ANY)) == NULL)
  648.     {
  649.       printf ("Can't allocate memory for XREF node!\n");
  650.       early_exit = TRUE;
  651.       kill_all_lists ();
  652.       cleanup ();
  653.     }
  654.  
  655.   if ((new_xref->name = (char *) alloc (strlen (name) + 1, MEMF_ANY)) == NULL)
  656.     {
  657.       printf ("Can't allocate memory for XREF node name field!\n");
  658.       early_exit = TRUE;
  659.       kill_all_lists ();
  660.       cleanup ();
  661.     }
  662.  
  663.   /* fill XREF struct */
  664.   strcpy (new_xref->name, name);
  665.  
  666.   new_xref->next = NULL;
  667.   curr_xref->next = new_xref;
  668.   curr_xref = curr_xref->next;
  669. }
  670.  
  671. void write_xrefs (void)
  672. {
  673.   BOOL past_head = FALSE;
  674.   XREF *curr, *temp;
  675.  
  676.   fprintf (dest, "\n");
  677.  
  678.   curr = xref;
  679.   do
  680.     {
  681.       temp = curr;
  682.       curr = curr->next;
  683.       if (past_head)
  684.     {
  685.       /* xdef or xref? */
  686.       if (temp->name[0] != '*')
  687.         {
  688.           /* XREF */
  689.           fprintf (dest, "\txref %s\n", temp->name);
  690.         }
  691.       else
  692.         {
  693.           /* XDEF -> first replace '*' with '_' */
  694.           temp->name[0] = '_';
  695.           fprintf (dest, "\txdef %s\n", temp->name);
  696.         }
  697.     }
  698.       if (!past_head)
  699.     past_head = TRUE;
  700.     }
  701.   while (curr != NULL);
  702. }
  703.  
  704. /* --BASIC DATA list functions-- */
  705.  
  706. void enter_BASDATA (char *literal)
  707. {
  708.   basdatapresent = TRUE;
  709.  
  710.   /* allocate memory for a new node & data */
  711.   if ((new_basdata = (BASDATA *) alloc (sizeof (BASDATA), MEMF_ANY)) == NULL)
  712.     {
  713.       printf ("Can't allocate memory for BASIC DATA node!\n");
  714.       early_exit = TRUE;
  715.       kill_all_lists ();
  716.       cleanup ();
  717.     }
  718.  
  719.   if ((new_basdata->literal = (char *) alloc (strlen (literal) + 1, MEMF_ANY)) == NULL)
  720.     {
  721.       printf ("Can't allocate memory for BASIC DATA node literal field!\n");
  722.       early_exit = TRUE;
  723.       kill_all_lists ();
  724.       cleanup ();
  725.     }
  726.  
  727.   /* fill BASDATA struct */
  728.   strcpy (new_basdata->literal, literal);
  729.  
  730.   new_basdata->next = NULL;
  731.   curr_basdata->next = new_basdata;
  732.   curr_basdata = curr_basdata->next;
  733. }
  734.  
  735. void write_basdata (void)
  736. {
  737.   BOOL past_head = FALSE;
  738.   BASDATA *curr, *temp;
  739.  
  740.   curr = basdata;
  741.  
  742.   if (curr->next != NULL)
  743.     {
  744.       fprintf (dest, "\n_BASICdata:\n");
  745.     }
  746.  
  747.   do
  748.     {
  749.       temp = curr;
  750.       curr = curr->next;
  751.       if (past_head)
  752.     {
  753.       fprintf (dest, "\t%s\n", temp->literal);
  754.     }
  755.       if (!past_head)
  756.     past_head = TRUE;
  757.     }
  758.   while (curr != NULL);
  759. }
  760.  
  761.  
  762. /* --structure functions-- */
  763.  
  764. void find_structmem_tail (SYM * symtabitem)
  765. {
  766. /* find end of structdef member list. */
  767.   tail_structmem = symtabitem->structmem;
  768.   while (tail_structmem->next != NULL)
  769.     tail_structmem = tail_structmem->next;
  770. }
  771.  
  772. BOOL structmem_exist (SYM * symtabitem, char *name)
  773. {
  774. /* seek a structure 
  775.    member. 
  776.  */
  777.  
  778.   curr_structmem = symtabitem->structmem->next;        /* head has no member data */
  779.  
  780.   while (curr_structmem != NULL)
  781.     {
  782.       if (strcmp (curr_structmem->name, name) == 0)
  783.     return (TRUE);
  784.       else
  785.     curr_structmem = curr_structmem->next;
  786.     }
  787.  
  788.   return (FALSE);
  789. }
  790.  
  791. void add_struct_member (SYM * symtabitem, char *name, int mtype, SYM * structtype)
  792. {
  793. /* add a member to a
  794.    structure definition.
  795.  */
  796.  
  797.   if (structmem_exist (symtabitem, name))
  798.     _error (61);
  799.   else
  800.     {
  801.       /* add a unique member */
  802.       if ((new_structmem = (STRUCM *) alloc (sizeof (STRUCM), MEMF_ANY)) == NULL)
  803.     {
  804.       printf ("Can't allocate memory for structdef node!\n");
  805.       early_exit = TRUE;
  806.       kill_all_lists ();
  807.       cleanup ();
  808.     }
  809.       else
  810.     {
  811.       /* enter member data */
  812.       strcpy (new_structmem->name, name);
  813.       new_structmem->type = mtype;
  814.       new_structmem->offset = symtabitem->size;
  815.  
  816.       /* link member into list */
  817.       find_structmem_tail (symtabitem);
  818.  
  819.       new_structmem->next = NULL;
  820.       tail_structmem->next = new_structmem;
  821.       curr_structmem = new_structmem;
  822.  
  823.       /* increment size of structure 
  824.          and hence, find next offset. 
  825.        */
  826.       switch (mtype)
  827.         {
  828.         case bytetype:
  829.           symtabitem->size += 1;
  830.           break;
  831.         case shorttype:
  832.           symtabitem->size += 2;
  833.           break;
  834.         case longtype:
  835.           symtabitem->size += 4;
  836.           break;
  837.         case singletype:
  838.           symtabitem->size += 4;
  839.           break;
  840.         case stringtype:
  841.           symtabitem->size += MAXSTRLEN;
  842.           curr_structmem->strsize = MAXSTRLEN;
  843.           break;
  844.         case structure:
  845.           symtabitem->size += structtype->size;
  846.           curr_structmem->strsize = structtype->size;
  847.           break;
  848.         }
  849.     }
  850.     }
  851. }
  852.